嚴格相等
與 寬鬆相等
是 JavaScript 的比較方法,由以下的運算子來比較結果是否相等,並依結果回傳布林值
===
嚴格相等運算子!==
嚴格不相等運算子==
寬鬆相等運算子!=
寬鬆不相等運算子console.log(1 === 1); // true - 嚴格相等
console.log(1 !== 1); // false - 嚴格不相等
console.log(1 == 1); // true - 寬鬆相等
console.log(1 != 1); // false - 寬鬆不相等
嚴格相等會比較 ===
、!==
運算子左右兩邊運算元的 型別
與 值
,來判定結果,最後依照結果回傳布林值
console.log(1 === 1); // true
console.log(1 === '1'); // false
console.log(1 !== 1); // false
console.log(1 !== '1'); // true
NaN (Not a Number)
- 意思為 "不是一個數值"
NaN
與 NaN
做比較,嚴格相等及寬鬆相等皆會回傳 false
console.log(NaN === NaN); // false
console.log(NaN == NaN); // false
-0
與 +0
雖然值不同,但比較結果為 true
console.log( -0 === +0); // true
console.log( -0 == +0); // true
// 其他數值範例
console.log( -1 === +1); // false
console.log( -1 == +1); // false
寬鬆相等會因做比較的兩者型別不同,而做 隱含轉型
- 先轉換成相同型別再做比較,但並非所有比較都會發生,是有其規則的
以下為寬鬆相等的運作表 (MDN - 相等比較):
寬鬆相等以 ==
、!=
運算子以及左右兩邊運算元組合而成,先依照規則轉型,再與 值
做比較,最後依照結果回傳布林值
console.log(1 == 1); // true
console.log(1 == '1'); // true
console.log(1 != 1); // false
console.log(1 != '1'); // false
以下為 布林型別
與 字串型別
在比較時,會先轉換為 數字型別
的範例:
字串型別
會先轉換成 數字型別
,再與 數字型別
相比較
console.log('1' == 1); // true
console.log(Number('1')); // 1 - 數字型別
Number()
、String()
為型別包裹器,想知道更多可看 Kuro - 基本型別包裹器
當 字串 0x11
與數值做比較,會先轉為數字型別 17
console.log(17 == '0x11'); // true
0x11
為十六進位,轉為十進位為17
console.log(Number(0x11)); // 17
布林型別
會先轉換成 數字型別
,再與 數字型別
做比較
console.log(Number(true)); // 1 - 數字型別
console.log(Number(false)); // 0 - 數字型別
// 肯定
console.log(true == 1); // true
console.log(false == 1); // false
// 否定
console.log(true != 1); // false
console.log(false != 1); // true
布林型別
與 字串型別
相比較時,兩者都會先轉成 數字型別
再做比較
// 布林轉數值
console.log(Number(true)); // 1 - 數值
console.log(Number(false)); // 0 - 數值
// 字串轉數值
console.log(Number('1')); // 1
console.log(Number('0')); // 0
// 肯定
console.log(true == '1'); // true
console.log(false == '0'); // true
// 否定
console.log(true != '1'); // false
console.log(false != '0'); // false
!0
的 0
會先轉換為 布林值 false
!false
再轉換為 布林值 true
布林值 true
與 字串 1
相比較則兩者都會先轉換為數值,因此結果為相等console.log('1' == !0); // true
console.log(!0); // true
需要注意的是 當 字串 true
、字串 false
轉換成數值時會轉成 NaN
// 布林轉數值
console.log(Number(true)); // 1 - 數值
console.log(Number(false)); // 0 - 數值
// 字串 true、字串 false 轉數值
console.log(Number('true')); // NaN
console.log(Number('false')); // NaN
console.log(true == 'true'); // false
console.log(false == 'false'); // false
Null
與 Undefined
比較時,不會轉為數字型別
Null
與Undefined
比較時只要看對方是否是Null
與Undefined
型別,否則結果皆為false
雖然用 Number(null)
可得出 數值 0
,但因 Null
與 Undefined
不會轉為數字型別比較,此例中得出結果為 false
console.log(Number(null)); // 0
console.log(Number(undefined)); // NaN
console.log(null == 0); // false
在寬鬆相等下 Null
與 Undefined
比較結果為 true
console.log(null == undefined); // true
console.log(null === undefined); // false
當物件與非物件做比較時,會使用包裹物件做轉換,可參考上面寬鬆相等運作圖表 ToPrimitive()
,它會透過 .toString()
、.valueOf()
方法轉換後再做比較,而物件與物件則是比較所參考的物件,而非它們的值
{} 物件
與[] 陣列
皆是屬於物件型別
此例中 陣列 [10]
使用包裹物件方式先轉換為原始型別,再做比較
console.log(10 == [10]); // true
當物件與字串做比較,物件會先使用 .toString()
轉換物件
陣列 ['A']
會先轉換為字串再與字串做比較
console.log(['A'].toString()); // A
console.log('A' == ['A']); // true
物件 {A: 'A'}
轉為字串會顯示 [object Object]
,所以會與 字串 [object Object]
相等
console.log([{A: 'A'}].toString()); // [object Object] - 字串型別
console.log('[object Object]' == {A: 'A'}); // true
當 物件型別
與 布林型別
做比較時,物件型別會透過包裹物件做轉換,布林型別則會轉為數字型別,再互相做比較
console.log([0] == false); // true
Null
與Undefined
比較時只要看對方是否是Null
與Undefined
型別,否則結果皆為false
console.log(['null'] == null); // false
console.log(['undefined'] == undefined); // false
物件與物件在相比時,比較的不是裡面的值,是兩者的參考位置,所以當物件與物件比較結果為 false
,主因是兩個的參考物件不同
雖然以下範例的值相同,但因參考物件不同,所以比較結果為 false
console.log({} == {}); // false
console.log([] == []); // false
變數 b
所取得的是 變數 a
的參考位置,兩者指向同個物件,所參考物件相同,所以 變數 a
與 變數 b
比較為 true
// 物件{} 範例
var a = {};
var b = a;
console.log(a == b); // true
console.log(a === b); // true
// 陣列[] 範例
var a = [];
var b = a;
console.log(a == b); // true
console.log(a === b); // true
console.log(0 == false); // number == number => true
console.log(0 == '0'); // number == number => true
console.log(0 == NaN); // 看對方是否是Null與Undefined => false
console.log(0 == undefined); // 看對方是否是 Null 與 Undefined => false
console.log('' == 0); // number == number => true
console.log('0' == ''); // string == string => false
console.log('' == false); // number == number => true
console.log('' == NaN); // 看對方是否是 Null 與 Undefined => false
console.log('' == undefined); // 看對方是否是 Null 與 Undefined => false
console.log(null == undefined); // 看對方是否是 Null 與 Undefined => true
console.log(null == false); // 看對方是否是 Null 與 Undefined => false
console.log(undefined == false); // 看對方是否是 Null 與 Undefined => false
console.log(null == [null]); // 看對方是否是 Null 與 Undefined => false
console.log(undefined == [undefined]); // 看對方是否是 Null 與 Undefined=>false
console.log([] == 0); // 物件轉字串再轉數值,number == number => true
console.log({} == 0); // [object, object] == 0 => false
console.log([] == ''); // 物件轉字串,string == string => true
console.log({} == ''); // 物件轉字串,[object, object] == string => false
console.log([] == false); // 物件轉數值,布林轉數值,number == number => true
console.log({} == false); // 布林轉數值,[object, object] == number => false